package org.example.study.JUC.CompletableFuture;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

public class ThreeMusketeers {
    public static void main(String[] args) throws InterruptedException {

        //CountDownLatch（倒计时闩锁） 基于计数器实现，初始值代表需要等待的事件数。工作线程完成任务后调用countDown()减少计数，主线程通过await()阻塞等待计数器归零。
        /**典型应用场景:
         * 主线程等待所有子任务完成
         * 服务启动等待依赖资源初始化
         * 并行计算任务同步
         */
        int threadCount = 2;
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " is done.");
                countDownLatch.countDown();
            }, "thread-" + i).start();
        }
        System.out.println("Waiting for threads to finish...");
        countDownLatch.await();
        System.out.println("All threads are done.");

        // CyclicBarrier（循环屏障） 让一组线程在屏障点相互等待，当所有线程都到达后执行预设操作并重置屏障，可循环使用。
        /**典型应用场景:
         * 多阶段数据处理（加载→处理→存储）
         * 并行计算的分步同步
         * 多线程测试的并发起点控制
         */
        Runnable barrierAction = () -> System.out.println("--- 所有线程到达屏障 ---");
        CyclicBarrier barrier = new CyclicBarrier(threadCount, barrierAction);
        for (int i = 0; i < threadCount; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " 加载阶段1数据");
                    barrier.await();  // 第一次等待

                    System.out.println(Thread.currentThread().getName() + " 处理阶段1数据");
                    barrier.await();  // 第二次等待（屏障重用）

                    System.out.println(Thread.currentThread().getName() + " 加载阶段2数据");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "Worker-"+i).start();
        }

        // Semaphore（信号量） 维护一组许可证，控制资源访问并发数。线程通过acquire()获取许可，release()释放许可。
        /**典型应用场景:
         * 数据库连接池管理
         * API限流控制
         * 资源池实现（如线程池）
         */
        int maxConnections = 3;
        Semaphore semaphore = new Semaphore(maxConnections);

        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                String threadName = Thread.currentThread().getName();
                try {
                    System.out.println(threadName + " 尝试获取连接");
                    semaphore.acquire();  // 获取许可

                    System.out.println(threadName + " 获取连接成功 | 剩余许可: "
                            + semaphore.availablePermits());
                    Thread.sleep(2000);  // 模拟数据库操作

                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();  // 释放许可
                    System.out.println(threadName + " 释放连接");
                    System.out.println("剩余许可: " + semaphore.availablePermits());
                }
            }, "Thread-"+i).start();
        }
    }


}
